如果你最近更新了 Android SDK,然後發現 flutter doctor --android-licenses 只吐出幾行警告就結束,該出現的授權提示一個也沒有,這篇是為你準備的。
執行 flutter doctor --android-licenses,畫面只吐出兩段警告就結束了,完全沒有出現以往那個「Review licenses that have not been accepted (y/N)?」的互動提示:

WARNING: The SDK Manager CLI tool (sdkmanager) is deprecated. Android CLI will be used instead.
The 'android' binary can also be found in the cmdline-tools directory, and 'android sdk' is the replacement for 'sdkmanager'.
To learn more about the Android CLI and how to use it, see the documentation (https://d.android.com/tools/agents/android-cli)
Warning: The --licenses option is no longer needed.
而 flutter doctor 則會一直卡在這個狀態:
[!] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
X Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
叫你去跑一個跑了也沒用的指令,無限迴圈。
Google 在新版的 Android SDK Command-line Tools 裡棄用了 sdkmanager,改推新的 android CLI。棄用從 22.0 就開始,但那時 sdkmanager 還是自己做事,--licenses 完全正常。
到了 23.0,sdkmanager 被改寫成一層轉譯腳本:它把舊旗標翻譯成 android sdk 的子指令再轉呼叫過去,--list 譯成 list --all、--update 譯成 update、--uninstall 譯成 remove。而 --licenses 沒有任何子指令可以對應,於是只回你一句 The --licenses option is no longer needed. 就結束。
Flutter 的 flutter doctor --android-licenses 底層正是去跑 sdkmanager --licenses,於是互動式的授權同意提示再也不會出現。
對應的 issue 是 flutter/flutter#191487。
--licenses是選項(旗標),不是子指令。分辨方式很直接:以-或--開頭的是選項,例如--licenses、-h、--sdk=PARAM;不帶橫線的裸字才是子指令,例如android sdk裡的sdk。所以sdkmanager --licenses的結構是「執行檔 + 選項」,而android sdk install的結構是「執行檔 + 子指令 + 子指令」。
Languages & Frameworks > Android SDK)。
latest 資料夾真的消失了:dir $env:LOCALAPPDATA\Android\Sdk\cmdline-tools
清單裡應該只剩下 22.0。這一步不能跳過,因為 Flutter 找 sdkmanager 時會優先使用 cmdline-tools\latest\bin\,找不到才退而挑版號最高的目錄。所以只要 latest 還在、裡面裝的又是 23.0,那你裝了 22.0 也等於白裝。
flutter doctor --android-licenses
熟悉的授權提示就回來了,一路 y 按到底即可:

6 of 7 SDK package licenses not accepted.
Review licenses that have not been accepted (y/N)? y
1/6: License android-googletv-license:
全部接受完之後再跑一次 flutter doctor,Android toolchain 就會變成綠色打勾了。
修了一半,而且還沒送到你手上。
修正(PR #191554)的做法是:當 Flutter 偵測到 --licenses option is no longer needed 這句話時,改成去看 <sdk>/licenses/ 目錄底下有沒有非空的授權檔案,只要有任何一個就視為授權已接受,繞過已經失效的 sdkmanager 輸出解析。
這個修正已經進了 master 和 beta,現行 stable 3.47.2 還沒有(本文查證日期為 2026-09-08)。所以如果你在網路上看到「3.48.0 已經修好了」,那指的是 beta 版號,不是你能用的正式版。
不過不必等到下一個大版本。Flutter 的 stable 次版號每三個週期才跳一次(3.41 → 3.44 → 3.47,下一個是 3.50),照正常節奏這個修正得等到 3.50。但 PR #191554 掛了 cp: beta 和 cp: stable 兩個 cherry-pick 標籤,而且兩邊都已經生效。stable 這邊走 PR #192133,2026-09-03 併進了 flutter-3.47-candidate.0,該分支的 CHANGELOG 也已經寫好 3.47.3 的條目,明列 issue #191487。
也就是說,修正會隨 stable 3.47.3 這個 hotfix 出貨,但要注意它修的是「判讀」而不是「接受」。PR #191554 只動了偵測授權狀態的那段程式碼,負責實際接受授權的 runLicenseManager() 一行都沒改,在 23.0 底下 flutter doctor --android-licenses 依然什麼都不做。所以 3.47.3 只能讓本來就接受過授權的人變回綠燈;如果你是全新環境、licenses 目錄還是空的,升級之後照樣卡住,還是得降版。
平心而論,Flutter 這邊反應算快,issue 開沒幾天 PR 就 merge 進 master 了。真正讓人火大的是上游。
第一,這是一個假裝成功的失敗。 Flutter 有兩條路都踩到這顆地雷。flutter doctor --android-licenses 走的是 runLicenseManager(),它直接執行 sdkmanager --licenses,把你的輸入原封不動轉給它,然後只看 exit code;普通的 flutter doctor 走的是 licensesAccepted,另外跑一次同樣的指令並解析輸出。
而 23.0 的 sdkmanager --licenses 只會印兩段警告、什麼都不做,然後回傳 exit code 0。這不是推測,sdkmanager.bat 裡就是這樣寫的:
if "%ARG%"=="--licenses" (
echo Warning: The --licenses option is no longer needed.>&2
set LICENSES_CONFIGURED=true
...
)
...
if "!SPECIAL_CMD!"=="" if "!PACKAGES!"=="" (
if "!LICENSES_CONFIGURED!"=="true" exit /b 0
於是 flutter doctor --android-licenses 拿到 0 就判定成功,而 flutter doctor 的三個正則全部比對不到,只能回報「狀態未知」。
它從頭到尾沒說過「成功」兩個字,但對腳本來說,exit code 0 就是成功;對你來說,畫面上就只是幾行看起來無關痛癢的警告。
而在 Flutter 專案裡,這個迴圈會漂亮地閉合起來。Flutter 的 gradle_errors.dart 有一個 licenseNotAcceptedHandler,專門攔截建置時出現的 You have not accepted the license agreements...,把訊息改寫成:
To resolve this, please run the following command in a Terminal:
flutter doctor --android-licenses
於是當你的 build 因為授權未接受而失敗時,Flutter 會明確地把你導向 flutter doctor --android-licenses,回到原點。
一個直接壞掉、回傳非 0 的指令,都比一個安靜地什麼都不做卻回傳 0 的指令好。
第二,新 CLI 根本沒有接手這個功能。 官方說 android sdk 是 sdkmanager 的替代品,那我們實際跑一次 android sdk -h 看看它提供哪些子指令:
Commands:
install Install SDK packages
update Update one or all packages to the latest version
remove Remove packages from the SDK
list List installed and available SDK packages

install、update、remove、list。沒了。沒有 licenses、沒有 --accept-licenses,Android CLI 的官方文件裡也找不到任何一個管理授權的指令。所謂的「替代品」,替代掉的是「你能夠明確看見並同意授權條款」這件事本身。授權該怎麼查、怎麼接受,新 CLI 一句話都沒交代,整件事變成一個黑箱。
第三,授權這塊完全沒有遷移指引。 官方在 sdkmanager 的文件頁掛了一句棄用聲明,要你改用 android sdk,還附了連結(只有英文版有這句,中文版至今沒翻譯過來,讀中文文件的人根本不會知道它被棄用了)。但那個連結點過去,就是上面那四個子指令的用法,授權隻字未提。而同一頁的「接受授權」章節到今天還寫著:
If you don't have Android Studio installed, or it's for a CI server or other headless Linux device without a GUI installed, do the following from the command line:
sdkmanager --licenses
那頁最後更新於 2026-09-02(UTC)。也就是說,官方一邊宣告這個工具棄用,一邊繼續教你用它去做一件它在 latest 版本上已經做不到的事。
至於變更紀錄,Command-line Tools 的官方 release notes 停在 2020 年 12 月的 5.0,之後一路到 23.0 一個字都沒補。本文那套降版步驟,出自 Flutter issue 底下一位使用者的留言。
棄用一個功能之前先提供替代品,這不是什麼高標準,這是基本禮貌。Google 這次給了過渡期,卻沒在過渡期裡把替代品做出來:22.0 警告了一整版,23.0 直接動手,而 android sdk 到今天依然沒有任何授權指令。
第四,Command-line Tools 把這個破壞性變更裝進了一個叫做 latest 的目錄。 SDK Manager 裡那個不帶版號的 Android SDK Command-line Tools (latest) 會裝進 cmdline-tools/latest/,而它現在指向的就是 23.0(勾選特定版號安裝時才會裝進 cmdline-tools/<版號>/)。
問題是,latest 這個目錄名被很多工具當成固定常數在用。Flutter 找 sdkmanager 時第一個就去看 cmdline-tools/latest/bin/;GitHub Actions 的 runner image 也一樣,不管下載回來的是哪一版,一律搬進 cmdline-tools/latest,再把 sdkmanager 的路徑寫死在那裡。
而 SDK Manager 裡那個不帶版號的選項,裝的永遠是這個固定路徑,至於裡面放哪一版則由 Google 決定。所以你在 Android Studio 勾的其實不是某個版本,而是「Google 當下指向的那一版」。今天勾就拿到 23.0;等 Google 把 latest 換成 24.0,你下次更新拿到的就是 24.0。
要在一個這麼多工具都預設指向的路徑上發布破壞性變更,那你至少要確保新版本能做到舊版本做得到的事。
sdkmanager --licenses;中文版連棄用聲明都還沒有)